# -*- coding: utf-8 -*-
# Copyright (C) 2018 Chris Jarry. All rights reserved.
# Name:
#   jarryShotHUD.py
# Author:
#   Jarry, WeChat: zhihuiJarry
#
# Usage:
#

import os
import time
import getpass
import math
import maya.OpenMaya as _OpenMaya
import maya.api.OpenMaya as om
import maya.api.OpenMayaRender as omr
import maya.api.OpenMayaUI as omui
import maya.mel as mel
import maya.cmds as cmds

from PySide2.QtCore import *
from PySide2.QtGui import *
from PySide2.QtWidgets import *


def maya_useNewAPI():
    """
    The presence of this function tells Maya that the plugin produces, and
    expects to be passed, objects created using the Maya Python API 2.0.
    """
    pass


def getCurrentFPS():
    '''
    returns the current frames per second as a number, rather than a useless string
    '''
    fpsDict = {"game": 15.0, "film": 24.0, "pal": 25.0, "ntsc": 30.0, "show": 48.0, "palf": 50.0, "ntscf": 60.0}
    return fpsDict[cmds.currentUnit(q=True, fullName=True, time=True)]


class jarryShotHudLocator(omui.MPxLocatorNode):
    """
    """

    NAME = "jarryShotHud"
    TYPE_ID = om.MTypeId(0x0011A885)
    DRAW_DB_CLASSIFICATION = "drawdb/geometry/jarryShotHud"
    DRAW_REGISTRANT_ID = "jarryShotHudNode"

    TEXT_ATTRS = ["topLeftText", "tlt", "topCenterText", "tct", "topRightText", "trt",
                  "bottomLeftText", "blt", "bottomCenterText", "bct", "bottomRightText", "brt"]

    TEXT_FONT = [u'Algerian', u'Arial', u'Arial Black', u'Arial Narrow', u'Arial Unicode MS',
                 u'Bahnschrift', u'Bahnschrift Condensed', u'Bahnschrift Light', u'Bahnschrift Light Condensed',
                 u'Bahnschrift Light SemiCondensed', u'Bahnschrift SemiBold', u'Bahnschrift SemiBold Condensed',
                 u'Bahnschrift SemiBold SemiConden', u'Bahnschrift SemiCondensed', u'Bahnschrift SemiLight',
                 u'Bahnschrift SemiLight Condensed',
                 u'Bahnschrift SemiLight SemiConde', u'Baskerville Old Face', u'Bauhaus 93', u'Bell MT',
                 u'Berlin Sans FB', u'Berlin Sans FB Demi',
                 u'Bernard MT Condensed', u'Bodoni MT Poster Compressed', u'Book Antiqua', u'Bookman Old Style',
                 u'Bookshelf Symbol 7',
                 u'Britannic Bold', u'Broadway', u'Brush Script MT', u'Calibri', u'Calibri Light', u'Californian FB',
                 u'Cambria',
                 u'Cambria Math', u'Candara', u'Candara Light', u'Centaur', u'Century', u'Century Gothic', u'Chiller',
                 u'Colonna MT',
                 u'Comic Sans MS', u'Consolas', u'Constantia', u'Cooper Black', u'Corbel', u'Corbel Light', u'Courier',
                 u'Courier New',
                 u'Ebrima', u'Fixedsys', u'Footlight MT Light', u'Franklin Gothic Medium', u'Freestyle Script',
                 u'Gabriola', u'Gadugi',
                 u'Garamond', u'Georgia', u'Haettenschweiler', u'Harlow Solid Italic', u'Harrington',
                 u'High Tower Text', u'HoloLens MDL2 Assets',
                 u'Impact', u'Informal Roman', u'Ink Free', u'Javanese Text', u'Jokerman', u'Juice ITC', u'Kristen ITC',
                 u'Kunstler Script',
                 u'Leelawadee', u'Leelawadee UI', u'Leelawadee UI Semilight', u'Lucida Bright', u'Lucida Calligraphy',
                 u'Lucida Console',
                 u'Lucida Fax', u'Lucida Handwriting', u'Lucida Sans Unicode', u'Magneto', u'Malgun Gothic',
                 u'Malgun Gothic Semilight',
                 u'Marlett', u'Matura MT Script Capitals', u'Microsoft Himalaya', u'Microsoft JhengHei',
                 u'Microsoft JhengHei Light',
                 u'Microsoft JhengHei UI', u'Microsoft JhengHei UI Light', u'Microsoft New Tai Lue',
                 u'Microsoft PhagsPa',
                 u'Microsoft Sans Serif', u'Microsoft Tai Le', u'Microsoft Uighur', u'Microsoft YaHei UI',
                 u'Microsoft YaHei UI Light',
                 u'Microsoft Yi Baiti', u'MingLiU-ExtB', u'MingLiU_HKSCS-ExtB', u'Mistral', u'Modern', u'Modern No. 20',
                 u'Mongolian Baiti',
                 u'Monotype Corsiva', u'MS Gothic', u'MS Outlook', u'MS PGothic', u'MS Reference Sans Serif',
                 u'MS Reference Specialty',
                 u'MS Sans Serif', u'MS Serif', u'MS UI Gothic', u'MT Extra', u'MV Boli', u'Myanmar Text',
                 u'Niagara Engraved', u'Niagara Solid',
                 u'Nirmala UI', u'Nirmala UI Semilight', u'Old English Text MT', u'Onyx', u'Palatino Linotype',
                 u'Parchment', u'Playbill',
                 u'PMingLiU-ExtB', u'Poor Richard', u'Ravie', u'Roman', u'Script', u'Segoe MDL2 Assets', u'Segoe Print',
                 u'Segoe Script',
                 u'Segoe UI', u'Segoe UI Black', u'Segoe UI Emoji', u'Segoe UI Historic', u'Segoe UI Light',
                 u'Segoe UI Semibold',
                 u'Segoe UI Semilight', u'Segoe UI Symbol', u'Showcard Gothic', u'SimSun-ExtB', u'Sitka Banner',
                 u'Sitka Display',
                 u'Sitka Heading', u'Sitka Small', u'Sitka Subheading', u'Sitka Text', u'Small Fonts', u'Snap ITC',
                 u'Stencil', u'Sylfaen',
                 u'Symbol', u'System', u'Tahoma', u'TeamViewer15', u'Tempus Sans ITC', u'Terminal', u'Times New Roman',
                 u'Trebuchet MS',
                 u'Verdana', u'Viner Hand ITC', u'Vivaldi', u'Vladimir Script', u'Webdings', u'Wide Latin',
                 u'Wingdings', u'Wingdings 2',
                 u'Wingdings 3', u'Yu Gothic', u'Yu Gothic Light', u'Yu Gothic Medium', u'Yu Gothic UI',
                 u'Yu Gothic UI Light',
                 u'Yu Gothic UI Semibold', u'Yu Gothic UI Semilight']

    def __init__(self):
        """
        """
        super(jarryShotHudLocator, self).__init__()

    def excludeAsLocator(self):
        """
        """
        return False

    @classmethod
    def creator(cls):
        """
        """
        return jarryShotHudLocator()

    @classmethod
    def initialize(cls):
        """
        """

        # ========jarry add ==========
        # msg_attr = om.MFnMessageAttribute()
        # msg_create = msg_attr.create("global", "cn")
        # jarryShotHudLocator.addAttribute(msg_create)
        # global setting

        # camera
        t_attr = om.MFnTypedAttribute()
        stringData = om.MFnStringData()
        obj = stringData.create("")
        camera_name = t_attr.create("camera", "cam", om.MFnData.kString, obj)
        t_attr.writable = True
        t_attr.storable = True
        t_attr.keyable = False
        jarryShotHudLocator.addAttribute(camera_name)
        # ep

        # seq
        # shot
        # arts
        attr = om.MFnTypedAttribute()
        obj = stringData.create("getpass.getuser()")
        arts = attr.create("Arts", "art", om.MFnData.kString, obj)
        attr.writable = True
        attr.storable = True
        attr.keyable = False
        jarryShotHudLocator.addAttribute(arts)
        # start
        attr = om.MFnTypedAttribute()
        obj = stringData.create("cmds.playbackOptions(query=True, minTime=True)")
        start_frame = attr.create("startFrame", "sf", om.MFnData.kString, obj)
        attr.writable = True
        attr.storable = True
        attr.keyable = False
        jarryShotHudLocator.addAttribute(start_frame)
        # end
        attr = om.MFnTypedAttribute()
        obj = stringData.create("cmds.playbackOptions(query=True, maxTime=True)")
        end_frame = attr.create("endFrame", "ef", om.MFnData.kString, obj)
        attr.writable = True
        attr.storable = True
        attr.keyable = False

        jarryShotHudLocator.addAttribute(end_frame)
        # current
        # font size
        attr = om.MFnNumericAttribute()
        font_scale = attr.create("fontScale", "fs", om.MFnNumericData.kFloat, 1.0)
        attr.writable = True
        attr.storable = True
        attr.keyable = True
        attr.setMin(0.1)
        attr.setMax(2.0)
        jarryShotHudLocator.addAttribute(font_scale)
        # text padding
        attr = om.MFnNumericAttribute()
        counter_h_position = attr.create("textHPadding", "tp", om.MFnNumericData.kShort, 10)
        attr.writable = True
        attr.storable = True
        attr.keyable = True
        attr.setMin(-20)
        attr.setMax(80)
        jarryShotHudLocator.addAttribute(counter_h_position)
        # text updown padding
        attr = om.MFnNumericAttribute()
        counter_v_position = attr.create("textVPadding", "tudp", om.MFnNumericData.kShort, 10)
        attr.writable = True
        attr.storable = True
        attr.keyable = True
        attr.setMin(-20)
        attr.setMax(80)
        jarryShotHudLocator.addAttribute(counter_v_position)
        # font key color
        attr = om.MFnNumericAttribute()
        font_key_color = attr.createColor("fontKeyColor", "fkc")
        attr.default = (1.0, 1.0, 1.0)
        attr.writable = True
        attr.storable = True
        attr.keyable = True
        jarryShotHudLocator.addAttribute(font_key_color)
        # font value color
        attr = om.MFnNumericAttribute()
        font_kalue_color = attr.createColor("fontValueColor", "fvc")
        attr.default = (1.0, 1.0, 1.0)
        attr.writable = True
        attr.storable = True
        attr.keyable = True
        jarryShotHudLocator.addAttribute(font_kalue_color)
        # font alpha
        attr = om.MFnNumericAttribute()
        font_alpha = attr.create("fontAlpha", "fa", om.MFnNumericData.kFloat, 1.0)
        attr.writable = True
        attr.storable = True
        attr.keyable = True
        attr.setMin(0.0)
        attr.setMax(1.0)
        jarryShotHudLocator.addAttribute(font_alpha)
        # font name
        # t_attr = om.MFnTypedAttribute()
        # stringData = om.MFnStringData()
        # obj = stringData.create("Consolas")
        # font_name = t_attr.create("fontName", "fn", om.MFnData.kString, obj)
        # t_attr.writable = True
        # t_attr.storable = True
        # t_attr.keyable = True
        # jarryShotHudLocator.addAttribute(font_name)

        eAttr = om.MFnEnumAttribute()
        # font_name = eAttr.create("fontName", "fn", cls.TEXT_FONT.index('Consolas'))
        font_name = eAttr.create("fontName", "fn", cls.TEXT_FONT.index('Consolas'))

        for i in range(0, len(cls.TEXT_FONT)):
            eAttr.addField(cls.TEXT_FONT[i], i)

        eAttr.writable = True
        eAttr.storable = True
        eAttr.keyable = True
        jarryShotHudLocator.addAttribute(font_name)
        # font Stretch
        attr = om.MFnNumericAttribute()
        font_stretch = attr.create("fontStrectch", "fst", om.MFnNumericData.kFloat, 1.0)
        attr.writable = True
        attr.storable = True
        attr.keyable = True
        attr.setMin(0.5)
        attr.setMax(2)
        jarryShotHudLocator.addAttribute(font_stretch)
        # topBorder
        attr = om.MFnNumericAttribute()
        top_border = attr.create("topBorder", "tbd", om.MFnNumericData.kBoolean, True)
        attr.writable = True
        attr.storable = True
        attr.keyable = True
        jarryShotHudLocator.addAttribute(top_border)
        # bottomBorder
        attr = om.MFnNumericAttribute()
        bottom_border = attr.create("bottomBorder", "bbd", om.MFnNumericData.kBoolean, True)
        attr.writable = True
        attr.storable = True
        attr.keyable = True
        jarryShotHudLocator.addAttribute(bottom_border)
        # border on outside
        attr = om.MFnNumericAttribute()
        outside_border = attr.create("outSideBorder", "osbd", om.MFnNumericData.kBoolean, False)
        attr.writable = True
        attr.storable = True
        attr.keyable = True
        jarryShotHudLocator.addAttribute(outside_border)
        # borderColor
        attr = om.MFnNumericAttribute()
        border_color = attr.createColor("borderColor", "bc")
        attr.default = (0.0, 0.0, 0.0)
        attr.writable = True
        attr.storable = True
        attr.keyable = True
        jarryShotHudLocator.addAttribute(border_color)
        # border alpha
        attr = om.MFnNumericAttribute()
        border_alpha = attr.create("borderAlpha", "ba", om.MFnNumericData.kFloat, 1.0)
        attr.writable = True
        attr.storable = True
        attr.keyable = True
        attr.setMin(0.0)
        attr.setMax(1.0)
        jarryShotHudLocator.addAttribute(border_alpha)
        # border scale
        attr = om.MFnNumericAttribute()
        border_scale = attr.create("borderScale", "bs", om.MFnNumericData.kFloat, 1.0)
        attr.writable = True
        attr.storable = True
        attr.keyable = True
        attr.setMin(0.5)
        attr.setMax(2.0)
        jarryShotHudLocator.addAttribute(border_scale)
        # line enbal
        attr = om.MFnNumericAttribute()
        line_enbal = attr.create("lineEnbal", "lb", om.MFnNumericData.kBoolean, True)
        attr.writable = True
        attr.storable = True
        attr.keyable = True
        jarryShotHudLocator.addAttribute(line_enbal)
        # lineColor
        attr = om.MFnNumericAttribute()
        line_color = attr.createColor("lineColor", "lc")
        attr.default = (0.0, 0.0, 0.0)
        attr.writable = True
        attr.storable = True
        attr.keyable = True
        jarryShotHudLocator.addAttribute(line_color)
        # line alpha
        attr = om.MFnNumericAttribute()
        line_alpha = attr.create("lineAlpha", "la", om.MFnNumericData.kFloat, 1.0)
        attr.writable = True
        attr.storable = True
        attr.keyable = True
        attr.setMin(0.0)
        attr.setMax(1.0)
        jarryShotHudLocator.addAttribute(line_alpha)
        # line scale
        attr = om.MFnNumericAttribute()
        line_scale = attr.create("lineScale", "ls", om.MFnNumericData.kShort, 2)
        attr.writable = True
        attr.storable = True
        attr.keyable = True
        attr.setMin(1)
        attr.setMax(10)
        jarryShotHudLocator.addAttribute(line_scale)
        # --------- group -------
        # enbal
        attr = om.MFnNumericAttribute()
        enbal = attr.create("Enbal", "enb", om.MFnNumericData.kBoolean, True)
        attr.writable = True
        attr.storable = True
        attr.keyable = True
        # enbal end
        # key
        t_attr = om.MFnTypedAttribute()
        stringData = om.MFnStringData()
        obj = stringData.create("Key")
        key = t_attr.create("Key", "kk", om.MFnData.kString, obj)
        t_attr.writable = True
        t_attr.storable = True
        t_attr.keyable = True
        # key end
        # value
        t_attr = om.MFnTypedAttribute()
        stringData = om.MFnStringData()
        obj = stringData.create("Value")
        key_value = t_attr.create("Value", "vv", om.MFnData.kString, obj)
        t_attr.writable = True
        t_attr.storable = True
        t_attr.keyable = True
        # value end
        # alignment
        eAttr = om.MFnEnumAttribute()
        localtion = eAttr.create("Alignment", "agt", 0)
        n = 0
        for i in range(0, len(cls.TEXT_ATTRS), 2):
            eAttr.addField(cls.TEXT_ATTRS[i], n)
            n += 1
        eAttr.writable = True
        eAttr.storable = True
        eAttr.keyable = True
        # alignment end
        # y_offset
        attr = om.MFnNumericAttribute()
        axis_y_offset = attr.create("AxisYOffset", "axyo", om.MFnNumericData.kFloat, 0.0)
        attr.writable = True
        attr.storable = True
        attr.keyable = True
        attr.setMin(-100.0)
        attr.setMax(100.0)
        # y_offset end
        # x_offset
        attr = om.MFnNumericAttribute()
        axis_x_offset = attr.create("AxisXOffset", "axxo", om.MFnNumericData.kFloat, 0.0)
        attr.writable = True
        attr.storable = True
        attr.keyable = True
        attr.setMin(-500.0)
        attr.setMax(500.0)
        # x_offset end
        group_attr = om.MFnCompoundAttribute()
        group_Padding = om.MObject()
        group_Padding = group_attr.create("Padding", "pad")
        group_attr.addChild(enbal)  # child 0
        group_attr.addChild(key)  # child 1
        group_attr.addChild(key_value)  # child 2
        group_attr.addChild(localtion)  # child 3
        group_attr.addChild(axis_y_offset)  # child 4
        group_attr.addChild(axis_x_offset)  # child 5

        group_attr.array = True
        group_attr.writable = True
        group_attr.storable = True
        group_attr.keyable = True
        group_attr.readable = True

        jarryShotHudLocator.addAttribute(group_Padding)


class jarryShotHudData(om.MUserData):
    """
    """

    def __init__(self):
        """
        """
        super(jarryShotHudData, self).__init__(False)  # don't delete after draw


class jarryShotHudDrawOverride(omr.MPxDrawOverride):
    """
    """

    NAME = "jarryShotHud_draw_override"

    def __init__(self, obj):
        """
        """
        super(jarryShotHudDrawOverride, self).__init__(obj, jarryShotHudDrawOverride.draw)

    def supportedDrawAPIs(self):
        """
        """
        return (omr.MRenderer.kAllDevices)

    def isBounded(self, obj_path, camera_path):
        """
        """
        return False

    def boundingBox(self, obj_path, camera_path):
        """
        """
        return om.MBoundingBox()

    def scene_name(self):
        untitled_file_name = mel.eval('untitledFileName()')
        name = _OpenMaya.MFileIO.currentFile()
        if name.endswith(untitled_file_name) and \
                cmds.file(q=1, sceneName=1) == '':
            return untitled_file_name
        else:
            return name

    def prepareForDraw(self, obj_path, camera_path, frame_context, old_data):
        """
        """
        data = old_data
        if not isinstance(data, jarryShotHudData):
            data = jarryShotHudData()
        fnDagNode = om.MFnDagNode(obj_path)
        st_str = fnDagNode.findPlug("startFrame", False).asString()
        et_str = fnDagNode.findPlug("endFrame", False).asString()

        data.camera_name = fnDagNode.findPlug("camera", False).asString()
        camera_path2 = frame_context.getCurrentCameraPath()
        camera = om.MFnCamera(camera_path2)
        focal_length = round(camera.focalLength, 2)
        fit_data = {0: "Fill", 1: "Horizontal", 2: "Vertical", 3: "Overscan"}
        filmFit = fit_data[camera.filmFit]
        data.filmFit = filmFit
        data.sceneName = os.path.basename(self.scene_name())
        data.sound = self.get_sound()
        data.st = int(eval(st_str))
        data.et = int(eval(et_str))
        data.total = data.et - data.st + 1
        data.frame = int(cmds.currentTime(q=True))
        data.fps = getCurrentFPS()
        data.year = time.strftime("%Y", time.localtime())
        data.month = time.strftime("%m", time.localtime())
        data.day = time.strftime("%d", time.localtime())
        data.hour = time.strftime("%H", time.localtime())
        data.minutes = time.strftime("%M", time.localtime())
        data.seconds = time.strftime("%S", time.localtime())

        data.w = cmds.getAttr('defaultResolution.width')
        data.h = cmds.getAttr('defaultResolution.height')

        data.asset = self.asset_count_text()
        try:
            data.arts = eval(fnDagNode.findPlug("Arts", False).asString())
        except:
            data.arts = fnDagNode.findPlug("Arts", False).asString()
        data.var = {'scene': data.sceneName,
                    'w': data.w,
                    'h': data.h,
                    'cam': str(camera_path2).replace('Shape', ''),
                    'fl': str(focal_length),
                    'fit': data.filmFit,
                    # 'tx': data.tx,
                    # 'ty': data.ty,
                    # 'tz': data.tz,
                    'juli': 0,
                    'st': data.st,
                    'et': data.et,
                    'total': data.total,
                    'frame': data.frame,
                    'fps': data.fps,
                    'Y': data.year,
                    'm': data.month,
                    'd': data.day, 'H': data.hour, 'M': data.minutes, 'S': data.seconds,
                    'arts': data.arts,
                    'sound': data.sound,
                    'asset': data.asset}
        try:
            cam_parent = cmds.listRelatives(camera_path2, p=1)
        except:
            return
        if cam_parent:
            cam_p = cam_parent[0]
            xtz = cmds.xform(cam_p, q=1, ws=1, t=1)
            data.tx = xtz[0]  # cmds.getAttr('%s.tx' % cam_p)
            data.ty = xtz[1]  # cmds.getAttr('%s.ty' % cam_p)
            data.tz = xtz[2]  # cmds.getAttr('%s.tz' % cam_p)

            # data.rx = cmds.getAttr('%s.rx' % cam_p)
            # data.ry = cmds.getAttr('%s.ry' % cam_p)
            # data.rz = cmds.getAttr('%s.rz' % cam_p)
            data.distance = round(math.sqrt(data.tx ** 2 + data.ty ** 2 + data.tz ** 2), 2)
            # data.rt =
            data.var.update({'juli': data.distance})
        else:
            data.tx = 0
            data.ty = 0
            data.tz = 0
            data.dis = 0
            data.var.update({'juli': data.distance})

        data.text_h_padding = fnDagNode.findPlug("textHPadding", False).asInt()
        data.text_v_padding = fnDagNode.findPlug("textVPadding", False).asInt()
        # border
        data.top_border = fnDagNode.findPlug("topBorder", False).asBool()
        data.bottom_border = fnDagNode.findPlug("bottomBorder", False).asBool()
        data.outside_border = fnDagNode.findPlug("outSideBorder", False).asBool()
        data.border_scale = fnDagNode.findPlug("borderScale", False).asFloat()

        r = fnDagNode.findPlug("borderColorR", False).asFloat()
        g = fnDagNode.findPlug("borderColorG", False).asFloat()
        b = fnDagNode.findPlug("borderColorB", False).asFloat()
        a = fnDagNode.findPlug("borderAlpha", False).asFloat()
        data.border_color = om.MColor((r, g, b, a))
        # line
        data.line_enbal = fnDagNode.findPlug("lineEnbal", False).asBool()
        data.line_scale = fnDagNode.findPlug("lineScale", False).asInt()
        r = fnDagNode.findPlug("lineColorR", False).asFloat()
        g = fnDagNode.findPlug("lineColorG", False).asFloat()
        b = fnDagNode.findPlug("lineColorB", False).asFloat()
        a = fnDagNode.findPlug("lineAlpha", False).asFloat()
        data.line_color = om.MColor((r, g, b, a))

        # font
        index = fnDagNode.findPlug("fontName", False).asInt()
        # print index
        # print jarryShotHudLocator.TEXT_FONT
        data.font_name = jarryShotHudLocator.TEXT_FONT[index]
        # print data.font_name
        data.font_scale = fnDagNode.findPlug("fontScale", False).asFloat()

        r = fnDagNode.findPlug("fontKeyColorR", False).asFloat()
        g = fnDagNode.findPlug("fontKeyColorG", False).asFloat()
        b = fnDagNode.findPlug("fontKeyColorB", False).asFloat()
        a = fnDagNode.findPlug("fontAlpha", False).asFloat()
        data.font_key_color = om.MColor((r, g, b, a))

        r = fnDagNode.findPlug("fontValueColorR", False).asFloat()
        g = fnDagNode.findPlug("fontValueColorG", False).asFloat()
        b = fnDagNode.findPlug("fontValueColorB", False).asFloat()
        a = fnDagNode.findPlug("fontAlpha", False).asFloat()
        data.font_value_color = om.MColor((r, g, b, a))

        data.font_stretch = fnDagNode.findPlug("fontStrectch", False).asFloat()

        padding_data = {}
        padding_grp = fnDagNode.findPlug('Padding', False)
        padding_count = padding_grp.numElements()
        for i in range(padding_count):
            isEnbal = padding_grp.elementByLogicalIndex(i).child(0).asBool()
            key = padding_grp.elementByLogicalIndex(i).child(1).asString()
            value = padding_grp.elementByLogicalIndex(i).child(2).asString()
            alignment = padding_grp.elementByLogicalIndex(i).child(3).asInt()
            axis_y_offset = padding_grp.elementByLogicalIndex(i).child(4).asFloat()
            axis_x_offset = padding_grp.elementByLogicalIndex(i).child(5).asFloat()

            padding_data[str(i)] = {"Enbal": isEnbal,
                                    "key": key,
                                    "value": value,
                                    "alignment": alignment,
                                    "axis_y_offset": axis_y_offset,
                                    "axis_x_offset": axis_x_offset}
        data.padding_data = padding_data

        return data

    def textWidth(self, text, font, s=1):
        metrics = QFontMetricsF(font)
        textWidth = metrics.width(text) * s
        # print textWidth
        return textWidth

    def hasUIDrawables(self):
        """
        """
        return True

    def addUIDrawables(self, obj_path, draw_manager, frame_context, data):
        """
        """
        if not isinstance(data, jarryShotHudData):
            return

        camera_path = frame_context.getCurrentCameraPath()
        camera = om.MFnCamera(camera_path)
        # print camera_path, data.camera_name, self.is_camera_match(camera_path, data.camera_name)
        if data.camera_name and self.camera_exists(data.camera_name) and not self.is_camera_match(camera_path,
                                                                                                  data.camera_name):
            return
        camera_aspect_ratio = camera.aspectRatio()
        device_aspect_ratio = cmds.getAttr("defaultResolution.deviceAspectRatio")
        vp_x, vp_y, vp_width, vp_height = frame_context.getViewportDimensions()
        vp_half_width = 0.5 * vp_width
        vp_half_height = 0.5 * vp_height
        vp_aspect_ratio = vp_width / float(vp_height)
        scale = 1.0

        if camera.filmFit == om.MFnCamera.kHorizontalFilmFit:
            mask_width = vp_width / camera.overscan
            mask_height = mask_width / device_aspect_ratio
        elif camera.filmFit == om.MFnCamera.kVerticalFilmFit:
            mask_height = vp_height / camera.overscan
            mask_width = mask_height * device_aspect_ratio
        elif camera.filmFit == om.MFnCamera.kFillFilmFit:
            if vp_aspect_ratio < camera_aspect_ratio:
                if camera_aspect_ratio < device_aspect_ratio:
                    scale = camera_aspect_ratio / vp_aspect_ratio
                else:
                    scale = device_aspect_ratio / vp_aspect_ratio
            elif camera_aspect_ratio > device_aspect_ratio:
                scale = device_aspect_ratio / camera_aspect_ratio

            mask_width = vp_width / camera.overscan * scale
            mask_height = mask_width / device_aspect_ratio

        elif camera.filmFit == om.MFnCamera.kOverscanFilmFit:
            if vp_aspect_ratio < camera_aspect_ratio:
                if camera_aspect_ratio < device_aspect_ratio:
                    scale = camera_aspect_ratio / vp_aspect_ratio
                else:
                    scale = device_aspect_ratio / vp_aspect_ratio
            elif camera_aspect_ratio > device_aspect_ratio:
                scale = device_aspect_ratio / camera_aspect_ratio

            mask_height = vp_height / camera.overscan / scale
            mask_width = mask_height * device_aspect_ratio
        else:
            om.MGlobal.displayError("[jarryShotHud] Unknown Film Fit value")
            return
        # print mask_height, mask_width

        mask_half_width = 0.5 * mask_width
        mask_x = vp_half_width - mask_half_width

        mask_half_height = 0.5 * mask_height
        mask_bottom_y = vp_half_height - mask_half_height
        mask_top_y = vp_half_height + mask_half_height

        border_height = int(0.05 * mask_height * data.border_scale)
        background_size = (int(mask_width) + 1, border_height)
        draw_manager.beginDrawable()
        draw_manager.setFontName(data.font_name)
        draw_manager.setFontSize(int((border_height - border_height * 0.15) * data.font_scale))

        outside_border = data.outside_border
        outside_border_pos = 0
        if outside_border:
            outside_border_pos = border_height

        if data.top_border:
            self.draw_border(draw_manager, om.MPoint(mask_x, mask_top_y - border_height + outside_border_pos),
                             background_size, data.border_color)
        if data.bottom_border:
            self.draw_border(draw_manager, om.MPoint(mask_x, mask_bottom_y - outside_border_pos), background_size,
                             data.border_color)

        # draw line of 9 gong ge
        if data.line_enbal:
            # vertical ====
            line_scale = max(1, int(data.line_scale * mask_height * 0.001))
            line_v_size = (int(mask_width), line_scale)
            line_ver_y_pos = (vp_height - mask_height) * 0.5 + mask_height / 3
            self.draw_border(draw_manager, om.MPoint(mask_x, line_ver_y_pos), line_v_size, data.line_color)
            line_ver_y2_pos = (vp_height - mask_height) * 0.5 + mask_height / 3 * 2
            self.draw_border(draw_manager, om.MPoint(mask_x, line_ver_y2_pos), line_v_size, data.line_color)
            # horizontal  |||
            line_h_size = (line_scale, int(mask_height))
            line_hor_x_pos = (vp_half_width - mask_half_width) + mask_width / 3
            self.draw_border(draw_manager, om.MPoint(line_hor_x_pos, mask_bottom_y), line_h_size, data.line_color)
            line_hor_x2_pos = (vp_half_width - mask_half_width) + mask_width / 3 * 2
            self.draw_border(draw_manager, om.MPoint(line_hor_x2_pos, mask_bottom_y), line_h_size, data.line_color)

        # font color
        key_color = data.font_key_color
        value_color = data.font_value_color

        padding_data = data.padding_data
        # print mask_height,device_aspect_ratio

        h = mask_height + border_height * 2
        ratio = mask_width / h
        # print h, mask_width
        # print ratio
        data.var.update({'bdh': int(data.w / ratio)})
        for index in padding_data:
            enbal = padding_data[index]['Enbal']
            if not enbal:
                continue
            key = padding_data[index]['key']
            value = padding_data[index]['value']
            for v in data.var:
                value = value.replace(u'$%s' % v, unicode(data.var.get(v)))

            alignment = padding_data[index]['alignment']
            key_width = self.textWidth(key, data.font_name,
                                       data.font_stretch) * mask_half_width * 0.0018 * data.font_scale * data.border_scale * (
                                    1 / device_aspect_ratio) * 2.5
            value_width = self.textWidth(value, data.font_name,
                                         data.font_stretch) * mask_half_width * 0.0018 * data.font_scale * data.border_scale * (
                                      1 / device_aspect_ratio) * 2.5
            # print 'key:', key_width
            # print 'value:', value_width
            padding_x = data.text_h_padding * mask_half_width * 0.0018 * data.font_scale
            padding_y = data.text_v_padding * mask_height * 0.002 * data.font_scale * data.border_scale

            axis_y_offset = padding_data[index][
                                'axis_y_offset'] * mask_height * 0.002 * data.font_scale * data.border_scale
            axis_x_offset = padding_data[index][
                                'axis_x_offset'] * mask_width * 0.002 * data.font_scale * data.border_scale
            if alignment == 0:
                # topLeftText
                alt = omr.MUIDrawManager.kLeft
                x, y = mask_x + padding_x + axis_x_offset, mask_top_y - border_height + axis_y_offset + padding_y
                x1, y1 = x + key_width, y

            elif alignment == 1:
                # topCenterText
                alt = omr.MUIDrawManager.kLeft
                x, y = vp_half_width - key_width + axis_x_offset, mask_top_y - border_height + axis_y_offset + padding_y
                x1, y1 = x + key_width, y
            elif alignment == 2:
                # topRightText
                alt = omr.MUIDrawManager.kRight
                x, y = mask_x + mask_width - padding_x - value_width + axis_x_offset, mask_top_y - border_height + axis_y_offset + padding_y
                x1, y1 = x + value_width, y
            elif alignment == 3:
                # bottomLeftText
                alt = omr.MUIDrawManager.kLeft
                x, y = mask_x + padding_x + axis_x_offset, mask_bottom_y + axis_y_offset - padding_y
                x1, y1 = x + key_width, y
            elif alignment == 4:
                # bottomCenterText
                alt = omr.MUIDrawManager.kLeft
                x, y = vp_half_width - key_width + axis_x_offset, mask_bottom_y + axis_y_offset - padding_y
                x1, y1 = x + key_width, y
            else:
                # bottomRightText
                alt = omr.MUIDrawManager.kRight
                x, y = mask_x + mask_width - padding_x - value_width + axis_x_offset, mask_bottom_y + axis_y_offset - padding_y
                x1, y1 = x + value_width, y
            draw_manager.setColor(key_color)
            # draw_manager.setFontWeight(key_width)
            self.draw_text(draw_manager, om.MPoint(x, y), key, alt, background_size)
            draw_manager.setColor(value_color)
            self.draw_text(draw_manager, om.MPoint(x1, y1), value, alt, background_size)

        draw_manager.endDrawable()

    def draw_border(self, draw_manager, position, background_size, color):
        """
        """
        draw_manager.text2d(position, " ", alignment=omr.MUIDrawManager.kLeft, backgroundSize=background_size,
                            backgroundColor=color)

    def draw_text(self, draw_manager, position, text, alignment, background_size):
        """
        """
        if (len(text) > 0):
            draw_manager.text2d(position, text, alignment=alignment, backgroundSize=background_size,
                                backgroundColor=om.MColor((0.0, 0.0, 0.0, 0.0)))
            # print draw_manager.getFontList()

    def asset_count_text(self):
        try:
            import jarryLibs.mayakit.JFileReference as jfr
            # import elsLibs as els
            reference_list = jfr.listReferences(parentNS=':', isLoaded=True)
            asset_data = {'c': [], 'p': [], 'e': []}
            for ref in reference_list:
                # aif = els.AssetInfoFromFile.AssetInfoFromFile(ref.path)
                file_name = os.path.basename(ref.path)
                asset_type = file_name.split('_')[0]
                if asset_type not in asset_data.keys():
                    continue
                if asset_type in asset_data:
                    asset_data[asset_type].append(ref.namespace)
                else:
                    asset_data[asset_type] = [ref.namespace]
            text = 'c: {} p: {} e: {}'.format(len(asset_data['c']), len(asset_data['p']), len(asset_data['e']))
            return text
        except:
            return 'Error!'

    def camera_exists(self, name):
        """
        """
        # ---------------------------------------------------------------------
        # om.MItDependencyNodes is only supported in Maya 2016.5 and newer
        # ---------------------------------------------------------------------
        # dg_iter = om.MItDependencyNodes(om.MFn.kCamera)
        # while not dg_iter.isDone():
        #     if dg_iter.thisNode().hasFn(om.MFn.kDagNode):
        #         camera_path = om.MDagPath.getAPathTo(dg_iter.thisNode())
        #         if self.is_camera_match(camera_path, name):
        #             return True
        #     dg_iter.next()
        # return False
        for cam in cmds.listCameras():
            if name in cam:
                return True

    def get_sound(self):
        gPlayBackSlider = mel.eval('$tmpVar=$gPlayBackSlider')
        sound = cmds.timeControl(gPlayBackSlider, q=True, sound=1)
        if sound:
            sound_file = cmds.getAttr('%s.filename' % sound)
            result = os.path.basename(sound_file) + '(%s)' % os.path.basename(os.path.dirname(sound_file))
            return result
        return "None"

    def is_camera_match(self, camera_path, name):
        """
        """
        path_name = camera_path.fullPathName()
        split_path_name = path_name.split('|')
        if len(split_path_name) >= 1:
            if split_path_name[-1] == name:
                return True
        if len(split_path_name) >= 2:
            if split_path_name[-2] == name:
                return True

        return False

    @staticmethod
    def creator(obj):
        """
        """
        return jarryShotHudDrawOverride(obj)

    @staticmethod
    def draw(context, data):
        """
        """
        return


def initializePlugin(obj):
    """
    """
    pluginFn = om.MFnPlugin(obj, "zhihui Jarry", "1.0.0", "Any")

    try:
        pluginFn.registerNode(jarryShotHudLocator.NAME,
                              jarryShotHudLocator.TYPE_ID,
                              jarryShotHudLocator.creator,
                              jarryShotHudLocator.initialize,
                              om.MPxNode.kLocatorNode,
                              jarryShotHudLocator.DRAW_DB_CLASSIFICATION)
    except:
        om.MGlobal.displayError("Failed to register node: {0}".format(jarryShotHudLocator.NAME))

    try:
        omr.MDrawRegistry.registerDrawOverrideCreator(jarryShotHudLocator.DRAW_DB_CLASSIFICATION,
                                                      jarryShotHudLocator.DRAW_REGISTRANT_ID,
                                                      jarryShotHudDrawOverride.creator)
    except:
        om.MGlobal.displayError("Failed to register draw override: {0}".format(jarryShotHudDrawOverride.NAME))


def uninitializePlugin(obj):
    """
    """
    pluginFn = om.MFnPlugin(obj)

    try:
        omr.MDrawRegistry.deregisterDrawOverrideCreator(jarryShotHudLocator.DRAW_DB_CLASSIFICATION,
                                                        jarryShotHudLocator.DRAW_REGISTRANT_ID)
    except:
        om.MGlobal.displayError("Failed to deregister draw override: {0}".format(jarryShotHudDrawOverride.NAME))

    try:
        pluginFn.deregisterNode(jarryShotHudLocator.TYPE_ID)
    except:
        om.MGlobal.displayError("Failed to unregister node: {0}".format(jarryShotHudLocator.NAME))


if __name__ == "__main__":
    plugin_name = "jarryShotHud.py"
    if cmds.pluginInfo(plugin_name, q=True, loaded=True):
        cmds.unloadPlugin(plugin_name)
    if not cmds.pluginInfo(plugin_name, q=True, loaded=True):
        cmds.loadPlugin(plugin_name)
    cmds.createNode("jarryShotHud")
